package com.android.lovely.ui.chat

import android.content.res.ColorStateList
import android.view.View
import android.view.ViewGroup
import androidx.core.graphics.toColorInt
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.android.lovely.databinding.ItemChatLoadBinding
import com.android.lovely.databinding.ItemChatLoadMoreBinding
import com.android.lovely.databinding.ItemChatReceiveBinding
import com.android.lovely.databinding.ItemChatReceiveImgBinding
import com.android.lovely.databinding.ItemChatSendBinding
import com.android.lovely.ext.MessageHelper.applyMessageWithStyle
import com.android.lovely.ext.ColorUtils.calculateColor
import com.android.lovely.ext.loadBlurredImage
import com.android.lovely.ext.loadWithPlaceholder
import com.android.lovely.ext.MessageHelper.roleStyle
import com.android.lovely.ext.MessageHelper.userStyle
import com.android.lovely.room.chat.database.BaseMessage
import com.android.lovely.room.chat.database.ImageMessage
import com.android.lovely.room.chat.database.LoadMoreMessage
import com.android.lovely.room.chat.database.LoadingMessage
import com.android.lovely.room.chat.database.ReceivedTextMessage
import com.android.lovely.room.chat.database.RegenerateMessage
import com.android.lovely.room.chat.database.SendTextMessage
import com.kotlin.extensions.inflater.LayoutInflaterExt.layoutInflater
import com.kotlin.extensions.view.ViewExt.clickable

/**
 *
 * @author why
 * @date 2025/3/27 17:41
 */

interface ContentInteractionCallback {
    fun onMediaClick(message: ImageMessage) {}
    fun onRetryClick(message: SendTextMessage) {}
    fun onRefreshClick(message: ReceivedTextMessage) {}
    fun onModifyClick(message: ReceivedTextMessage) {}
    fun onExtendedClick(message: BaseMessage, view: View) {}
    fun onFetchMore() {}
}

class InteractionAdapter : RecyclerView.Adapter<BaseContentHolder>() {

    val items = mutableListOf<BaseMessage>()

    private var interactionCallback: ContentInteractionCallback? = null

    fun setInteractionCallback(callback: ContentInteractionCallback) {
        this.interactionCallback = callback
    }

    fun findIndex(predicate: (BaseMessage) -> Boolean): Int {
        return items.indexOfFirst(predicate)
    }

    fun getList(): MutableList<BaseMessage> {
        return items
    }

    fun add(data: List<BaseMessage>, index: Int = items.size) {
        items.addAll(index, data)
        notifyItemRangeInserted(index, data.size)
    }

    fun add(data: BaseMessage, index: Int = 0) {
        items.add(index, data)
        notifyItemInserted(index)
    }

    fun set(position: Int, content: BaseMessage) {
        items[position] = content
        notifyDataSetChanged()
    }

    fun updateList(it: List<BaseMessage>) {
        items.clear()
        items.addAll(it)
        notifyDataSetChanged()
    }

    fun remove(data: BaseMessage) {
        val index = items.indexOfFirst { it == data }
        if (index > -1) {
            remove(index)
        }
    }

    fun remove(index: Int) {
        items.removeAt(index)
        notifyItemRemoved(index)
        notifyItemRangeChanged(index, items.size - index)
    }

    override fun getItemViewType(position: Int): Int {
        return when (items[position]) {
            is SendTextMessage -> 1
            is ReceivedTextMessage, is RegenerateMessage -> 2
            is ImageMessage -> 3
            is LoadingMessage -> 4
            is LoadMoreMessage -> 5
            else -> 1
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseContentHolder {
        return when (viewType) {
            1 -> OutgoingTextHolder(parent)
            2 -> IncomingTextHolder(parent)
            3 -> IncomingMediaHolder(parent)
            4 -> ProcessingHolder(parent)
            5 -> FetchMoreHolder(parent)
            else -> IncomingTextHolder(parent)
        }
    }

    override fun getItemCount(): Int {
        return items.size
    }

    override fun onBindViewHolder(holder: BaseContentHolder, position: Int) {
        holder.bind(items[position])
    }

    inner class OutgoingTextHolder(
        parent: ViewGroup, private val binding: ItemChatSendBinding = ItemChatSendBinding.inflate(
            parent.layoutInflater, parent, false
        )
    ) : BaseContentHolder(binding.root) {
        override fun bind(message: BaseMessage) {
            message as SendTextMessage
            binding.message.text = message.message.applyMessageWithStyle(userStyle)
            binding.message.backgroundTintList = ColorStateList.valueOf(userStyle.backgroundColor.calculateColor(userStyle.backgroundColorAlpha))
            binding.retry.isVisible = message.isSendFail
            binding.retry.clickable {
                binding.retry.isVisible = false
                interactionCallback?.onRetryClick(message)
            }
            binding.message.setOnLongClickListener {
                interactionCallback?.onExtendedClick(message, binding.message)
                true
            }
        }
    }

    inner class IncomingTextHolder(
        parent: ViewGroup,
        private val binding: ItemChatReceiveBinding = ItemChatReceiveBinding.inflate(
            parent.layoutInflater, parent, false
        )
    ) : BaseContentHolder(binding.root) {
        override fun bind(message: BaseMessage) {
            message as ReceivedTextMessage
            binding.message.text = message.message.applyMessageWithStyle(roleStyle)
            binding.translated.text = message.translate.applyMessageWithStyle(roleStyle)
            binding.clContent.backgroundTintList = ColorStateList.valueOf(roleStyle.backgroundColor.calculateColor(roleStyle.backgroundColorAlpha))
            binding.llOperation.isVisible = message.showEdit
            if (message.translate.isEmpty() && message.translating) {
                binding.transitionLoading.isVisible = true
                binding.llTranslated.isVisible = true
                binding.translated.isVisible = false
            } else {
                binding.transitionLoading.isVisible = false
                binding.llTranslated.isVisible = message.translate.isNotEmpty()
                binding.translated.isVisible = message.translate.isNotEmpty()
            }
            binding.regenerate.clickable { interactionCallback?.onRefreshClick(message) }
            binding.edit.clickable { interactionCallback?.onModifyClick(message) }
            binding.root.setOnLongClickListener {
                interactionCallback?.onExtendedClick(message, binding.message)
                true
            }
        }
    }

    inner class IncomingMediaHolder(
        parent: ViewGroup,
        private val binding: ItemChatReceiveImgBinding = ItemChatReceiveImgBinding.inflate(
            parent.layoutInflater, parent, false
        )
    ) : BaseContentHolder(binding.root) {
        override fun bind(message: BaseMessage) {
            message as ImageMessage
            binding.apply {
                clLock.isVisible = message.unlock.not()
                if (message.unlock) {
                    image.loadWithPlaceholder(message.message)
                } else {
                    image.loadBlurredImage(message.message)
                }
                tvCollect.text = message.intimacyValue.toString()
                tvDiamond.text = message.point.toString()
                tvCollect.isVisible = message.intimacyValue > 0
                tvDiamond.isVisible = message.point > 0
                tvOr.isVisible = message.intimacyValue > 0 && message.point > 0
            }

            binding.image.clickable { interactionCallback?.onMediaClick(message) }
            binding.clLock.clickable { interactionCallback?.onMediaClick(message) }
            binding.root.setOnLongClickListener {
                interactionCallback?.onExtendedClick(message, binding.root)
                true
            }
        }
    }

    private var isProcessing = false

    fun completeProcessing() {
        isProcessing = false
    }

    override fun onViewAttachedToWindow(holder: BaseContentHolder) {
        super.onViewAttachedToWindow(holder)
        if (holder is FetchMoreHolder) {
            if (!isProcessing) {
                isProcessing = true
                interactionCallback?.onFetchMore()
            }
        }
    }
}

abstract class BaseContentHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    open fun bind(message: BaseMessage) {
    }
}

class ProcessingHolder(
    parent: ViewGroup,
    private val binding: ItemChatLoadBinding = ItemChatLoadBinding.inflate(
        parent.layoutInflater, parent, false
    )
) : BaseContentHolder(binding.root) {
    override fun bind(message: BaseMessage) {
        super.bind(message)
        binding.clContent.backgroundTintList =
            if(message.isSend) {
                ColorStateList.valueOf(roleStyle.backgroundColor.calculateColor(userStyle.backgroundColorAlpha))
            } else {
                ColorStateList.valueOf(roleStyle.backgroundColor.calculateColor(roleStyle.backgroundColorAlpha))
            }

        if(roleStyle.backgroundColor == "#7C7C7E".toColorInt() ||
            roleStyle.backgroundColor == "#D2D2D2".toColorInt() ||
            roleStyle.backgroundColor == "#FFFFFF".toColorInt()){
            binding.ivLoading.setAnimation("loading_dark.json")
        } else {
            binding.ivLoading.setAnimation("loading_light.json")
        }

    }
}

class FetchMoreHolder(
    parent: ViewGroup, binding: ItemChatLoadMoreBinding = ItemChatLoadMoreBinding.inflate(
        parent.layoutInflater, parent, false
    )
) : BaseContentHolder(binding.root)